﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace ServerListerner.Helper
{
    /// <summary>
    /// 信号通道 用作线程间通讯
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class MpscChannel<T>
    {
        private readonly ConcurrentQueue<T> _queue = new ConcurrentQueue<T>();
        private readonly ManualResetEvent _resetEvent=new ManualResetEvent(false);
        /// <summary>
        /// 发送信号 
        /// </summary>
        /// <param name="Producer"></param>
        public void Send(T Producer)
        {
            if (Producer is null)
                return;
            _queue.Enqueue(Producer);
            _resetEvent.Set();
        }
        /// <summary>
        /// 接收信号
        /// 无信号时不会等待信号
        /// </summary>
        /// <param name="result"></param>
        /// <returns></returns>
        public bool TryReceive(out T result)
        {
            result = default(T);
            if(!_queue.TryDequeue(out result))
                return false;
            if (_queue.IsEmpty || _queue.Count <= 0)
                _resetEvent.Reset();
            return true;

        }
        /// <summary>
        /// 接收信号
        /// 无信号时会等待信号
        /// </summary>
        /// <returns></returns>
        public T Receive() {
            while (true)
            {
                if (TryReceive(out T result))
                {
                    if (_queue.IsEmpty || _queue.Count <= 0)
                        _resetEvent.Reset();
                    return result;
                }
                _resetEvent.WaitOne();
            }
        }

    }
}
